using System;
using System.Linq.Expressions;
using log4net;

namespace Karma.Framework.Core.Domain.Tools.Import.Configuration.Fluent
{
    public class FluentPropertyConfiguration<T, TProperty>
        where TProperty : DomainObject
    {
        private static readonly ILog LOG = LogManager.GetLogger(typeof(FluentPropertyConfiguration<,>).Name);

        protected FluentTransientConfiguration<T> _entityConfiguration;

        public FluentPropertyConfiguration(FluentTransientConfiguration<T> eConf, Expression<Func<T, TProperty>> expression)
        {
            if (expression.Body.NodeType != ExpressionType.MemberAccess)
            {
                throw new InvalidOperationException("La expresion para configurar una propiedad debe ser del tipo MemberAccess.");
            }
            var exp = (MemberExpression)expression.Body;
            var member = exp.Member;

            _configuration = new PropertyConfiguration(member.Name, member.ReflectedType);
            _entityConfiguration = eConf;
        }

        public FluentTransientConfiguration<T> ReferencedBy(Expression<Func<TProperty, string>> expression) 
        {
            if (expression.Body.NodeType != ExpressionType.MemberAccess)
            {
                throw new InvalidOperationException("La expresion para configurar una propiedad debe ser del tipo MemberAccess.");
            }
            var exp = (MemberExpression)expression.Body;
            var member = exp.Member;

            _configuration.Reference = member.Name;
            // TODO: Revisar como obtener el tipo de dato de la propiedad en la expresion
            _configuration.ReferenceType = typeof(string);//member.ReflectedType;

            if (LOG.IsDebugEnabled)
            {
                LOG.Debug(string.Format("Reference property [{0}] of type [{1}] by its property [{2}] with type [{3}]",
                    _configuration.Name, _configuration.Type.FullName, _configuration.Reference, _configuration.ReferenceType.FullName));
            }
            return _entityConfiguration;
        }

        protected PropertyConfiguration _configuration;
        public PropertyConfiguration Configuration
        {
            get
            {
                return _configuration;
            }
        }

        public FluentTransientConfiguration<T> Formula(Expression<Func<T, object>> expression)
        {
            //_configuration.Formula = expression;
            return _entityConfiguration;
        }
    }
}